package com.osilon.updater.tasks;

import java.lang.reflect.Modifier;
import java.util.List;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;

import com.osilon.asm.OsilonClassNode;
import com.osilon.util.ClassCache;

public class ChatTask extends Task {
	public boolean canProcess(OsilonClassNode node) {
		return node.constants.get("help") != null;
	}

	public void process(ClassCache cache, OsilonClassNode node) {
		MethodNode mn = node.constants.get("help").get(0);
		
		mn.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/osilon/OsilonHandler", "handleChatCommand", "(Lcom/osilon/hooks/ChatCommand;)V"));
		mn.instructions.insert(new VarInsnNode(Opcodes.ALOAD, 1));
	
		String chatCommandName = mn.desc;
		chatCommandName = chatCommandName.substring(2, chatCommandName.indexOf(';'));
		
		OsilonClassNode n = cache.getClass(chatCommandName);
		
		n.interfaces.add("com/osilon/hooks/ChatCommand");
		
		for(FieldNode fn : n.public_fields) {
			if(fn.desc.equals("Ljava/lang/String;")) {
				n.addGetter("getCommand", fn.desc, fn.name, fn.desc);
			} else {
				n.addGetter("getSenderInfo", "Lcom/osilon/hooks/SenderInfo;", fn.name, fn.desc);
			
				OsilonClassNode senderInfo = cache.getClass(fn.desc.substring(1, fn.desc.length() - 1));
				senderInfo.interfaces.add("com/osilon/hooks/SenderInfo");
				
				String displayName = null;
				String getStringName = null;
				
				for(MethodNode m : (List<MethodNode>) senderInfo.methods) {
					if(m.desc.equals("(Ljava/lang/String;)V")) {
						displayName = m.name;
					} else {
						getStringName = m.name;
					}
				}
				
				for(OsilonClassNode ocn : cache.getClasses()) {
					for(String i : ocn.interfaces) {
						if(i.equals(senderInfo.name)) {
							ocn.addMethodDelegate("display", "(Ljava/lang/String;)V", displayName, "(Ljava/lang/String;)V", false);
							ocn.addMethodDelegate("getString", "()Ljava/lang/String;", getStringName, "()Ljava/lang/String;", false);
						} 
					}
				}
			}
		}
	}
}
